import Bus from "./bus";
import store from "./store";
const config = toRef(store);

export type usbip_port_device = {
    id: string,
    speed: string,
    attach_id: string,
    server: string,
    device_id: string,
    vendor: string,
    product: string,
    address: string,
    raw: string,
}

export type usbip_list_device = {
    id: string,
    address: string,
    vendor: string,
    product: string,
    described: Array<string> | string,
    raw: string,
}

export type usbip_servers = {
    [propName: string]: boolean
}


export type usbip = {
    devices: {
        local: { [propName: string]: usbip_list_device },
        remote: { [propName: string]: { [propName: string]: usbip_list_device } }
    },
    port: { [propName: string]: usbip_port_device }
    servers: usbip_servers
}

interface WSResult {
    api: string,
    code?: number,
    data: any,
    [propName: string]: unknown
}

let server_info: {
    usbip: usbip,
} = reactive({
    usbip: {
        devices: {
            local: {},
            remote: {},
        },
        port: {},
        servers: {}
    }
})

let handles: { [propName: string]: any } = {}
let ticks: { [propName: string]: any } = reactive({})
let cb_list: { [propName: string]: any } = {}

function get_msg(result: WSResult) {
    if (!('api' in result)) {
        ElMessage.error("api is null" + new String(JSON.stringify(result)));
        console.log("api is null", result);
        return;
    }

    // console.log(`收到消息${result.api}`, result);
    if (result.api == "get_info") {
        ticks['refresh_info'] = 0;
        server_info.usbip = result.data;
        return;
    } else if (result.api == "refresh") {
        ticks['refresh'] = 0;
        if (typeof result.code === 'number') {
            if (result.code == 0)
                ElMessage.success(`刷新成功`);
            else if (result.code != 0) {
                let err_str = `刷新失败:${result.data}`
                ElMessage.error(err_str);
                console.log(err_str)
            }
        }
        return;
    } else if (result.api == "attach") {
        ticks['attach'] = 0;
        if (typeof result.code === 'number') {
            if (result.code == 0)
                ElMessage.success(`绑定远程USB设备成功`);
            else if (result.code != 0) {
                let err_str = `绑定远程USB设备失败:${result.data}`
                ElMessage.error(err_str);
                console.log(err_str)
            }
        }
        return;
    } else if (result.api == "detach") {
        ticks['detach'] = 0;
        if (typeof result.code === 'number') {
            if (result.code == 0)
                ElMessage.success(`解除远程USB设备成功`);
            else if (result.code != 0) {
                let err_str = `解除远程USB设备失败:${result.data}`
                ElMessage.error(err_str);
                console.log(err_str)
            }
        }
        return;
    } else if (result.api == "bind") {
        ticks['bind'] = 0;
        if (typeof result.code === 'number') {
            if (result.code == 0) {
                ElMessage.success(`分享本地USB设备成功`);
                refresh_info();
            }
            else if (result.code != 0) {
                let err_str = `分享本地USB设备失败:${result.data}`
                ElMessage.error(err_str);
                console.log(err_str)
            }
        }
        return;
    } else if (result.api == "unbind") {
        ticks['unbind'] = 0;
        if (typeof result.code === 'number') {
            if (result.code == 0) {
                ElMessage.success(`成功解除已分享的USB设备`);
                refresh_info();
            }
            else if (result.code != 0) {
                let err_str = `解除已分享的USB设备失败:${result.data}`
                ElMessage.error(err_str);
                console.log(err_str)
            }
        }
        return;
    } else if (result.api == "local") {
        let data_str = JSON.stringify(result.data);
        let target_str = JSON.stringify(server_info.usbip.devices.local);
        if (data_str != target_str) {
            if (data_str.length > target_str.length)
                ElMessage.success(`本地接入新的 USB 设备`);
            else
                ElMessage.warning(`本地 USB 设备 已拔出`);
        }
        server_info.usbip.devices.local = result.data;
        return;
    } else if (result.api == "ports") {
        let data_str = JSON.stringify(result.data);
        let target_str = JSON.stringify(server_info.usbip.port);
        if (data_str != target_str) {
            if (data_str.length > target_str.length)
                ElMessage.success(`已挂载网络USB设备`);
            else
                ElMessage.warning(`已卸载网络USB设备`);
        }
        server_info.usbip.port = result.data;
        return;
    } else if (result.api == "devices") {
        const { ip, list } = result.data
        let data_str = JSON.stringify(list);
        let target_str = JSON.stringify(server_info.usbip.devices.remote[ip]);
        if (data_str != target_str) {
            if (data_str.length > target_str.length)
                ElMessage.success(`${ip} : 插入新 USB 设备`);
            else
                ElMessage.warning(`${ip} : 拔出新 USB 设备`);
        }
        server_info.usbip.devices.remote[ip] = list;
        return;
    } else if (result.api == "servers") {
        let data_str = JSON.stringify(result.data);
        let target_str = JSON.stringify(server_info.usbip.servers);
        if (data_str != target_str) {
            if (data_str.length > target_str.length)
                ElMessage.success(`发现新 USBIP 服务器`);
            else
                ElMessage.warning(`远程 USBIP 服务器 已关闭`);
        }
        server_info.usbip.servers = result.data;
        return;
    }
}

function api_req(api: string, data: any, name: string, timeoutString?: string, err_cb?: any, success_cb?: any) {
    let tick = Date.now();
    cb_list[name] = {};
    if (success_cb)
        cb_list[name].ok = success_cb;
    if (err_cb)
        cb_list[name].error = err_cb;
    if (name) {
        ticks[name] = tick;
        if (handles[name]) {
            clearTimeout(handles[name]);
        }
        handles[name] = setTimeout(() => {
            if (ticks[name]) {
                ElMessage.error(timeoutString);
                ticks[name] = 0; // 清除超时
                if (cb_list[name]?.error) {
                    cb_list[name].error();
                    delete cb_list[name].error; // 清除回调
                }
            }
        }, 3 * 1000); // 3秒后超时
    }
    Bus.emit("push.msg", {
        api,
        data: data || {}
    });
}

/* 获取 USBIP 信息 */
function refresh_info() {
    api_req("get_info", {}, 'refresh_info', "获取 USBIP 信息超时");
}

/* 刷新 本地USB列表(0)/已挂载远程USB设备(1)/局域网内的USBIP服务器(2)/远程USB列表(3) */
function refresh(type: number) {
    api_req("refresh", type, 'refresh', "获取 USBIP 信息超时");
}

/* 绑定远程USB设备 */
function attach(ip: string, id: string) {
    api_req("attach", { ip, id }, 'attach', "绑定远程USB设备超时");
}

/* 解除已绑定远程USB设备 */
function detach(id: string) {
    if (id.length == 0) {
        ElMessage.error("端口错误");
    }
    api_req("detach", id, 'detach', "解除已绑定远程USB设备超时");
}

/* 分享本地USB设备 */
function bind(id: string) {
    api_req("bind", id, 'bind', "分享本地USB设备超时");
}

/* 解除已分享本地USB设备 */
function unbind(id: string) {
    api_req("unbind", id, 'unbind', "解除已分享本地USB设备超时");
}

Bus.on("update:msg", get_msg);
config.value["server"] = server_info; // 设备信息

export default {
    refresh,
    refresh_info,
    attach,
    detach,
    bind,
    unbind,
    ticks,
};
